#include <iostream>
#include <fstream>
#include <sstream>

#include <auxiliares.h>
#include <matriz.h>
#include <parser.h>
#include <paths.h>

using namespace std;

unsigned int este = 0;
unsigned int oeste = 0;
unsigned int norte = 0;
unsigned int sur = 0;

void obtenerDimensiones(matriz<uint8_t>& matriz_mascara)
{
	/* Busco el punto mas al oeste */
		
	unsigned int i;
	
	for(i = 0; i < COLUMNAS_IMG; i++)
	{
		for(unsigned int j = 0; j < FILAS_IMG; j++)
		{
			if(matriz_mascara[j][i] != 0)
			{
				oeste = i;
				goto salir1;
			}
		}
	}
	
salir1:

	/* Busco el punto mas al este */
			
	for(i = oeste; i < COLUMNAS_IMG; i++)
	{
		bool todaviaHayElem = false;
		for(unsigned int j = 0; j < FILAS_IMG; j++)
		{
			if(matriz_mascara[j][i] != 0)
			{
				todaviaHayElem = true;
				break;
			}
		}
			
		if(!todaviaHayElem)
		{
			este = i;
			break;
		}
	}
	
	/* Busco el punto mas al norte */
		
	for(i = 0; i < FILAS_IMG; i++)
	{
		for(unsigned int j = 0; j < COLUMNAS_IMG; j++)
		{
			if(matriz_mascara[i][j] != 0)
			{
				norte = i;
				goto salir2;
			}
		}
	}
	
salir2:

	/* Busco el punto mas al sur */
			
	for(i = norte; i < FILAS_IMG; i++)
	{
		bool todaviaHayElem = false;
		for(unsigned int j = 0; j < COLUMNAS_IMG; j++)
		{
			if(matriz_mascara[i][j] != 0)
			{
				todaviaHayElem = true;
				break;
			}
		}
			
		if(!todaviaHayElem)
		{
			sur = i;
			break;
		}
	}
	
	filas_imagen = sur - norte;
	colum_imagen = este - oeste;
	
	if(mostrar_debug)
		cout << endl << "Dimensiones imagen recortada: " << filas_imagen << " filas, " << colum_imagen << " columnas." << endl << endl;
}

matriz<uint8_t> matriz_mascara;

bool parsearMascaraImagen()
{
	/* Matriz donde guardaremos el archivo parseado */
	
	matriz_mascara = matriz<uint8_t>(FILAS_IMG, COLUMNAS_IMG, 0);
	 	
	ifstream archivoin; 	
	archivoin.open(path_imagen_mask(tipo_imagen));

	if(not(archivoin.is_open()))
	{
		cout << "ERROR: No se encuentra el archivo " << path_imagen_mask(tipo_imagen) << "!" << endl;
		return false;
	}
	
	// Leemos el archivo de entrada
	
	stringstream ss_in;
  	string line = "";
	
	getline(archivoin, line);		// Leo la version	
	getline(archivoin, line);		// Leo el comentario

	ss_in << archivoin.rdbuf();
	
	int columnas, filas;
	ss_in >> columnas >> filas;		// Leo las columnas y las filas
	
	int valor;
	ss_in >> valor;					// Leo el maximo valor de la imagen
			
	for(int fila = 0; fila < FILAS_IMG; fila++)
		for(int columna = 0; columna < COLUMNAS_IMG; columna++)
		{
			if(ss_in.eof()) 	// Si el archivo se termina antes de completar la matriz, algo anda mal...
			{
				cout << "ERROR: El archivo " << path_imagen_mask(tipo_imagen) << " contiene menos filas o columnas que las necesarias" << endl;
				archivoin.close();
				return false;
			}

			ss_in >> valor;			
			matriz_mascara[fila][columna] = (uint8_t) valor;
		}
		
	archivoin.close();
	
	 /* Seteamos el centro y el radio de la esfera */
 	
 	obtenerDimensiones(matriz_mascara);
 	
 	return true;	
}

bool parsearImagen(matriz<uint8_t> &m, int num)
{	
	ifstream archivoin; 	
	archivoin.open(path_imagen(tipo_imagen, num_imagenes[num]));
	
	if(not(archivoin.is_open()))
	{
		cout << "ERROR: No se encuentra el archivo " << path_imagen(tipo_imagen, num_imagenes[num]) << "!" << endl;
		return false;
	}
		
	ofstream archivout;
	if(mostrar_recortes)
	{
		archivout.open(path_imagen_out(tipo_imagen, num_imagenes[num]));	
		archivout << "P2" << endl << "#imagenrecortada" << endl << colum_imagen << " " << filas_imagen << endl << 255 << endl;
	}
	
	// Leemos el archivo de entrada
	
	stringstream ss_in;
  	string line = "";
	
	getline(archivoin, line);		// Leo la version	
	getline(archivoin, line);		// Leo el comentario

	ss_in << archivoin.rdbuf();
	
	int columnas, filas;
	ss_in >> columnas >> filas;		// Leo las columnas y las filas
	
	int valor;
	ss_in >> valor;					// Leo el maximo valor de la imagen
 			
	for(unsigned int fila = 0; fila < FILAS_IMG; fila++)
		for( unsigned int columna = 0; columna < COLUMNAS_IMG; columna++)
		{
			if(ss_in.eof()) /* Si el archivo se termina antes de completar la matriz, algo anda mal... */
			{
				cout << "ERROR: El archivo " << path_imagen_out(tipo_imagen, num_imagenes[num]) << " contiene menos filas o columnas que las necesarias" << endl;
				archivoin.close();
				return false;
			}
			
			ss_in >> valor;
			
			if(norte <= fila && fila < sur && oeste <= columna && columna < este)
			{				
				m[fila - norte][columna - oeste] = (matriz_mascara[fila][columna]) ? (uint8_t) valor : 0;
							
				if(mostrar_recortes) archivout << ((matriz_mascara[fila][columna]) ? valor : 0) << endl;
			}
		}
		
	archivoin.close();	
	if(mostrar_recortes) archivout.close();
				 	
	return true;
}
 	
bool parsearImagenes(matriz<uint8_t>& m1, matriz<uint8_t>& m2, matriz<uint8_t>& m3)
{
	/* Llamo a la funcion parsearArchivo para cada imagen */

	if(!parsearImagen(m1, 0) || !parsearImagen(m2, 1) || !parsearImagen(m3, 2)) return false;
	return true; 	
}
